Copie ***** La première question à se poser =============================== Dans le code C++, il faut faire attention au signe = en se posant la question : **Que se passe-t-il lorsqu'on écrit : A = B ?** Dans tous les cas, la variable *A* va contenir une information identique à la variable *B*. Cependant, deux scénarios peuvent se produire : * Soit la variable *A* est une copie indépendante de la variable *B* et ces deux variables vont évoluer séparément dans le programme : toute action ou modification de l'une ne se reportera pas sur l'autre. * Soit la variable *A* est une référence à la variable *B* et, dans ce cas, elle est juste un alias vers la variable *B* : lorsque l'on utilise le nom *A*, on manipule en fait la variable originale *B*. .. note:: Il existe un troisième scénario où la variable *A* est une copie partielle de la variable *B*. Dans ce cas, certains éléments de la variable *A* sont des copies et d'autres des références. A notre niveau, nous éviterons cette situation car elle est source de nombreux bugs. La réponse à cette question n'est pas immédiate car elle dépend fortement du contexte et notamment du type de *A* et de *B*. Nous allons dans la suite examiner différents scénarios en les testant par des exemples. Comportement pour les affectations ================================== Pour les types fondamentaux --------------------------- Veuillez exécuter le code suivant dans votre environnement préféré, puis analysez les affichages. .. code-block:: cpp #include int main() { // type entier int a = 10; int b = a; b++; std::cout << a << " " << b << std::endl; // type double double c = 5; double d = c; d++; std::cout << c << " " << d << std::endl; // type bool double e = true; double f = e; f = !f; std::cout << e << " " << f << std::endl; } .. quiz:: affectationTypeFond :title: Affectations et types fondamentaux Pour chaque type testé, indiquez si l'affirmation correspondante est vraie ou fausse : .. csv-table:: :widths: 10 :delim: ! :quiz:`{"type":"TF","answer":"T"}` L'affectation sur des variables de type entier produit une copie. :quiz:`{"type":"TF","answer":"T"}` L'affectation sur des variables de type double produit une copie. :quiz:`{"type":"TF","answer":"T"}` L'affectation sur des variables de type booléen produit une copie. Pour les structures ------------------- Examinons maintenant le type structure. Veuillez exécuter le code suivant dans votre environnement préféré, analysez ensuite les affichages. .. code-block:: cpp #include struct v { int x; int y; }; int main() { // type structure v B; B.x = 10; B.y = 20; v A; A = B; // le cas qui nous intéresse A.x += 5; A.y += 5; // les affichages std::cout < void F(int a, double b, bool c) { std::cout << "Entrée de fonction : " << a << " " << b << " " << c << std::endl; a += 1; b += 1; c = !c; std::cout << "Sortie de fonction : " << a << " " << b << " " << c << std::endl; } int main() { // type entier int a = 10; double b = 20.0; bool c = true; std::cout << "Avant l'appel : " << a << " " << b << " " << c << std::endl; F(a,b,c); std::cout << "Après l'appel : " << a << " " << b << " " << c << std::endl; } .. quiz:: FondParamFnt :title: Passage de paramètres et types fondamentaux Pour chaque type testé, indiquez si l'affirmation correspondante est vraie ou fausse : .. csv-table:: :widths: 10 :delim: ! :quiz:`{"type":"TF","answer":"T"}` Le passage de paramètres avec un type entier produit une copie. :quiz:`{"type":"TF","answer":"T"}` Le passage de paramètres avec un type double produit une copie. :quiz:`{"type":"TF","answer":"T"}` Le passage de paramètres avec un type booléen produit une copie. Cas des structures ------------------ Le langage a-t-il voulu rester dans la logique des comportements précédents ou a-t-il choisi une autre stratégie ? Veuillez exécuter le code suivant, puis analysez les résultats. .. code-block:: cpp #include struct v { int x; int y; }; void F(v a) { std::cout << "Entrée de fonction : " << a.x << " " << a.y << std::endl; a.x += 1; a.y += 2; std::cout << "Sortie de fonction : " << a.x << " " << a.y << std::endl; } int main() { // type structure v a; a.x = 10; a.y = 20; std::cout << "Avant l'appel : " << a.x << " " << a.y << std::endl; F(a); std::cout << "Après l'appel : " << a.x << " " << a.y << std::endl; } .. quiz:: ParamStruct :title: Passage de paramètres et structure Indiquez si l'affirmation suivante est vraie ou fausse : .. csv-table:: :widths: 10 :delim: ! :quiz:`{"type":"TF","answer":"T"}` Le passage de paramètres avec un type structure produit une copie des informations contenues dans la structure. Conclusion ---------- Suite à nos tests, nous constatons que le C++ a choisi d'avoir un comportement homogène pour l'affectation et le passage d'arguments et ceci pour l'ensemble des types testés. En résumé, nous pouvons conclure par : .. panels:: :column: col-lg-10 p-2 **REGLE** : En C++, l'affectation et le passage d'arguments se font toujours par **copie** aussi pour les types fondamentaux que pour les structures.